Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Node / ReticulumProjects / MeshChatX.git / files / tests / frontend / archivesPage.security.test.js

Displaying Raw • Download


tests/frontend/archivesPage.security.test.js bce42bcdce0e7d2c6d78228e864a4cd1d974cc82 (bce42bcd) Text, 9.47 KB

T8b949e// SPDX-License-Identifier: 0BSD

Tff7b72import Tb4b4b4{ Te6edf3mount Tb4b4b4} Tff7b72from Ta5d6ff"@vue/test-utils"Tb4b4b4;
Tff7b72import Tb4b4b4{ Te6edf3describeTb4b4b4, Te6edf3itTb4b4b4, Te6edf3expectTb4b4b4, Te6edf3vi Tb4b4b4} Tff7b72from Ta5d6ff"vitest"Tb4b4b4;
Tff7b72import Te6edf3ArchivesPage Tff7b72from Ta5d6ff"@/components/archives/ArchivesPage.vue"Tb4b4b4;

Tff7b72function Te6edf3mountArchivesTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3routerPush Tff7b72= Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72return Tb4b4b4{
Te6edf3wrapperTff7b72: Te6edf3mountTb4b4b4(Te6edf3ArchivesPageTb4b4b4, Tb4b4b4{
Tffa657globalTff7b72: Tb4b4b4{
Te6edf3mocksTff7b72: Tb4b4b4{
Te6edf3$tTff7b72: Tb4b4b4(Te6edf3keyTb4b4b4) Tb4b4b4=> Te6edf3keyTb4b4b4,
Te6edf3$routerTff7b72: Tb4b4b4{ Te6edf3pushTff7b72: Te6edf3routerPush Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Te6edf3stubsTff7b72: Tb4b4b4{
Te6edf3MaterialDesignIconTff7b72: Tff7b72trueTb4b4b4,
Te6edf3ArchiveSidebarTff7b72: Tff7b72trueTb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4,
Te6edf3routerPushTb4b4b4,
Tb4b4b4}Tb4b4b4;
Tb4b4b4}

Tff7b72function Te6edf3randTextTb4b4b4(Te6edf3lenTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3alphabet Tff7b72= Ta5d6ff"abc<>\"'`\\/\u0000\n\r`topic_id="Tb4b4b4;
Tff7b72let Te6edf3s Tff7b72= Ta5d6ff""Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72let Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3lenTb4b4b4; Te6edf3iTff7b72++Tb4b4b4) Tb4b4b4{
Te6edf3s Tff7b72+= Te6edf3alphabetTb4b4b4[Tb4b4b4(Tffa657MathTb4b4b4.Te6edf3randomTb4b4b4(Tb4b4b4) Tff7b72* Te6edf3alphabetTb4b4b4.Te6edf3lengthTb4b4b4) Tff7b72| T79c0ff0Tb4b4b4]Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3sTb4b4b4;
Tb4b4b4}

Tff7b72function Te6edf3assertNoDangerousHtmlPatternsTb4b4b4(Te6edf3htmlTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3lower Tff7b72= Te6edf3htmlTb4b4b4.Te6edf3toLowerCaseTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3lowerTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<script"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3lowerTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<iframe"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3lowerTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"javascript:"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3lowerTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toMatchTb4b4b4(Ta5d6ff/<[^>]*\bonerror\s*=/Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3lowerTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toMatchTb4b4b4(Ta5d6ff/<[^>]*\bonload\s*=/Tb4b4b4)Tb4b4b4;
Tb4b4b4}

Te6edf3describeTb4b4b4(Ta5d6ff"Archives page viewing-archive surface (security / fuzz)"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3nastyPaths Tff7b72= Tb4b4b4[
Ta5d6ff"/page/article.mu`topic_id=40"Tb4b4b4,
Ta5d6ff"/page/article.mu`topic_id=40`extra"Tb4b4b4,
Ta5d6ff"/forum/thread.mu`sort=hot"Tb4b4b4,
Ta5d6ff"/../../../etc/passwd"Tb4b4b4,
Ta5d6ff"javascript:alert(1)"Tb4b4b4,
Ta5d6ff"<script>alert(1)</script>"Tb4b4b4,
Ta5d6ff"a"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff6000Tb4b4b4)Tb4b4b4,
Tb4b4b4]Tb4b4b4;

Tff7b72const Te6edf3nastyContents Tff7b72= Tb4b4b4[
Ta5d6ff"<img src=x onerror=alert(1)>"Tb4b4b4,
Ta5d6ff"<svg/onload=alert(1)>"Tb4b4b4,
Ta5d6ff"`>>{{constructor.constructor('return this')()}}"Tb4b4b4,
Ta5d6ff"# Title\n[link](javascript:alert(1))"Tb4b4b4,
Ta5d6ff"\x00"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff20Tb4b4b4)Tb4b4b4,
Tb4b4b4]Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"renderFullContent sanitizes .html archives"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Tb4b4b4{ Te6edf3wrapper Tb4b4b4} Tff7b72= Te6edf3mountArchivesTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3out Tff7b72= Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3renderFullContentTb4b4b4(Tb4b4b4{
Te6edf3page_pathTff7b72: Ta5d6ff"/page/evil.html"Tb4b4b4,
Te6edf3contentTff7b72: Ta5d6ff'<body><img src=x onerror=alert(1)><a href="javascript:alert(1)">x</a></body>'Tb4b4b4,
Te6edf3destination_hashTff7b72: Ta5d6ff"a"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff32Tb4b4b4)Tb4b4b4,
Te6edf3hashTff7b72: Ta5d6ff"b"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff32Tb4b4b4)Tb4b4b4,
Te6edf3idTff7b72: T79c0ff1Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3assertNoDangerousHtmlPatternsTb4b4b4(Te6edf3outTb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"heuristic micron archives isolate http and mesh links"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Tb4b4b4{ Te6edf3wrapper Tb4b4b4} Tff7b72= Te6edf3mountArchivesTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3hash Tff7b72= Ta5d6ff"aa"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff16Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3out Tff7b72= Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3renderFullContentTb4b4b4(Tb4b4b4{
Te6edf3page_pathTff7b72: Ta5d6ff"/forum/thread"Tb4b4b4,
Te6edf3contentTff7b72:
Ta5d6ff"`Hi`\n`[Phish`http://evil.example/login]`\n`[Node`bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:/page/index.mu]`"Tb4b4b4,
Te6edf3destination_hashTff7b72: Te6edf3hashTb4b4b4,
Te6edf3idTff7b72: T79c0ff2Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3outTb4b4b4.Te6edf3toLowerCaseTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toMatchTb4b4b4(Ta5d6ff/href\s*=\s*["']?\s*https?:/iTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3outTb4b4b4)Tb4b4b4.Te6edf3toMatchTb4b4b4(Ta5d6ff/data-action\s*=\s*["']openNode["']/iTb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"renderFullContent never throws; returns a string for fuzzed paths and bodies"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Tb4b4b4{ Te6edf3wrapper Tb4b4b4} Tff7b72= Te6edf3mountArchivesTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72let Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< T79c0ff90Tb4b4b4; Te6edf3iTff7b72++Tb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3page_path Tff7b72= Te6edf3nastyPathsTb4b4b4[Te6edf3i Tff7b72% Te6edf3nastyPathsTb4b4b4.Te6edf3lengthTb4b4b4] Tff7b72+ Te6edf3randTextTb4b4b4(Te6edf3i Tff7b72% T79c0ff7Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3content Tff7b72= Te6edf3nastyContentsTb4b4b4[Te6edf3i Tff7b72% Te6edf3nastyContentsTb4b4b4.Te6edf3lengthTb4b4b4] Tff7b72+ Te6edf3randTextTb4b4b4(T79c0ff40Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3archive Tff7b72= Tb4b4b4{
Te6edf3page_pathTb4b4b4,
Te6edf3contentTb4b4b4,
Te6edf3destination_hashTff7b72: Ta5d6ff"a"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff64Tb4b4b4)Tb4b4b4,
Te6edf3hashTff7b72: Ta5d6ff"b"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff64Tb4b4b4)Tb4b4b4,
Te6edf3idTff7b72: Te6edf3i Tff7b72+ T79c0ff1Tb4b4b4,
Tb4b4b4}Tb4b4b4;
Te6edf3expectTb4b4b4(Tb4b4b4(Tb4b4b4) Tb4b4b4=> Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3renderFullContentTb4b4b4(Te6edf3archiveTb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toThrowTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3out Tff7b72= Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3renderFullContentTb4b4b4(Te6edf3archiveTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Tff7b72typeof Te6edf3outTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff"string"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tb4b4b4(Te6edf3archiveTb4b4b4.Te6edf3page_path Tff7b72|| Ta5d6ff""Tb4b4b4)Tb4b4b4.Te6edf3splitTb4b4b4(Ta5d6ff"`"Tb4b4b4)Tb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4.Te6edf3toLowerCaseTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3endsWithTb4b4b4(Ta5d6ff".html"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3assertNoDangerousHtmlPatternsTb4b4b4(Te6edf3outTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"archiveViewerClasses picks safe viewer classes for adversarial page_path values"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Tb4b4b4{ Te6edf3wrapper Tb4b4b4} Tff7b72= Te6edf3mountArchivesTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3cases Tff7b72= Tb4b4b4[
Tb4b4b4{ Te6edf3page_pathTff7b72: Ta5d6ff"/page/article.mu`topic_id=40"Tb4b4b4, Te6edf3expectRichTff7b72: Tff7b72true Tb4b4b4}Tb4b4b4,
Tb4b4b4{ Te6edf3page_pathTff7b72: Ta5d6ff"/page/readme.html"Tb4b4b4, Te6edf3expectRichTff7b72: Tff7b72trueTb4b4b4, Te6edf3expectHtmlTff7b72: Tff7b72true Tb4b4b4}Tb4b4b4,
Tb4b4b4{ Te6edf3page_pathTff7b72: Ta5d6ff"javascript:alert(1)"Tb4b4b4, Te6edf3expectRichTff7b72: Tff7b72false Tb4b4b4}Tb4b4b4,
Tb4b4b4{ Te6edf3page_pathTff7b72: Ta5d6ff"../../../etc/passwd"Tb4b4b4, Te6edf3expectRichTff7b72: Tff7b72false Tb4b4b4}Tb4b4b4,
Tb4b4b4]Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Tb4b4b4{ Te6edf3page_pathTb4b4b4, Te6edf3expectRichTb4b4b4, Te6edf3expectHtml Tb4b4b4} Tff7b72of Te6edf3casesTb4b4b4) Tb4b4b4{
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3viewingArchive Tff7b72= Tb4b4b4{ Te6edf3page_path Tb4b4b4}Tb4b4b4;
Tff7b72const Te6edf3classes Tff7b72= Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3archiveViewerClassesTb4b4b4;
Te6edf3expectTb4b4b4(Tffa657ArrayTb4b4b4.Te6edf3isArrayTb4b4b4(Te6edf3classesTb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3classesTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"wrap-break-word"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3classesTb4b4b4.Te6edf3includesTb4b4b4(Ta5d6ff"nomad-page-rich"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Te6edf3expectRichTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3expectHtmlTb4b4b4) Tb4b4b4{
Te6edf3expectTb4b4b4(Te6edf3classesTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"nomad-page-html-host"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3viewingArchive Tff7b72= Tff7b72nullTb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"openInNomadnet uses router.push with nomadnetwork route and query only"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Tb4b4b4{ Te6edf3wrapperTb4b4b4, Te6edf3routerPush Tb4b4b4} Tff7b72= Te6edf3mountArchivesTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3openInNomadnetTb4b4b4(Tb4b4b4{
Te6edf3idTff7b72: T79c0ff40Tb4b4b4,
Te6edf3destination_hashTff7b72: Ta5d6ff"deadbeef"Tb4b4b4,
Te6edf3page_pathTff7b72: Ta5d6ff"/page/article.mu`topic_id=40"Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3routerPushTb4b4b4)Tb4b4b4.Te6edf3toHaveBeenCalledWithTb4b4b4(Tb4b4b4{
Te6edf3nameTff7b72: Ta5d6ff"nomadnetwork"Tb4b4b4,
Te6edf3paramsTff7b72: Tb4b4b4{ Te6edf3destinationHashTff7b72: Ta5d6ff"deadbeef" Tb4b4b4}Tb4b4b4,
Te6edf3queryTff7b72: Tb4b4b4{
Te6edf3pathTff7b72: Ta5d6ff"/page/article.mu`topic_id=40"Tb4b4b4,
Te6edf3archive_idTff7b72: T79c0ff40Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"muExportBasename neutralizes path separators in the basename"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Tb4b4b4{ Te6edf3wrapper Tb4b4b4} Tff7b72= Te6edf3mountArchivesTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3base Tff7b72= Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3muExportBasenameTb4b4b4(Tb4b4b4{
Te6edf3page_pathTff7b72: Ta5d6ff"../../../secret/x.mu"Tb4b4b4,
Te6edf3hashTff7b72: Ta5d6ff"abc"Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3baseTb4b4b4.Te6edf3includesTb4b4b4(Ta5d6ff"/"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3baseTb4b4b4.Te6edf3includesTb4b4b4(Ta5d6ff".."Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"onArchiveContentClick routes nomadnet links and scrolls fragment anchors"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Tb4b4b4{ Te6edf3wrapperTb4b4b4, Te6edf3routerPush Tb4b4b4} Tff7b72= Te6edf3mountArchivesTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3holder Tff7b72= Tffa657documentTb4b4b4.Te6edf3createElementTb4b4b4(Ta5d6ff"div"Tb4b4b4)Tb4b4b4;
Te6edf3holderTb4b4b4.Te6edf3innerHTML Tff7b72=
Ta5d6ff'<a class="nomadnet-link" data-nomadnet-url="abc123:/p.mu`q=1">n</a>' Tff7b72+
Ta5d6ff'<div id="frag ment">target</div><a href="#frag%20ment">f</a>'Tb4b4b4;
Tffa657documentTb4b4b4.Te6edf3bodyTb4b4b4.Te6edf3appendChildTb4b4b4(Te6edf3holderTb4b4b4)Tb4b4b4;
Tff7b72try Tb4b4b4{
Tff7b72const Te6edf3nomadA Tff7b72= Te6edf3holderTb4b4b4.Te6edf3querySelectorTb4b4b4(Ta5d6ff"a.nomadnet-link"Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3fragTarget Tff7b72= Te6edf3holderTb4b4b4.Te6edf3querySelectorTb4b4b4(Ta5d6ff"#frag\\ ment"Tb4b4b4)Tb4b4b4;
Te6edf3fragTargetTb4b4b4.Te6edf3scrollIntoView Tff7b72= Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3fragA Tff7b72= Te6edf3holderTb4b4b4.Te6edf3querySelectorTb4b4b4(Ta5d6ff'a[href^="#"]'Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3clickOn Tff7b72= Tb4b4b4(Te6edf3elTb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3ev Tff7b72= Tff7b72new Te6edf3MouseEventTb4b4b4(Ta5d6ff"click"Tb4b4b4, Tb4b4b4{ Te6edf3bubblesTff7b72: Tff7b72trueTb4b4b4, Te6edf3cancelableTff7b72: Tff7b72true Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tffa657ObjectTb4b4b4.Te6edf3definePropertyTb4b4b4(Te6edf3evTb4b4b4, Ta5d6ff"target"Tb4b4b4, Tb4b4b4{ Te6edf3valueTff7b72: Te6edf3el Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3onArchiveContentClickTb4b4b4(Te6edf3evTb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3evTb4b4b4;
Tb4b4b4}Tb4b4b4;
Tff7b72const Te6edf3nomadEv Tff7b72= Te6edf3clickOnTb4b4b4(Te6edf3nomadATb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3routerPushTb4b4b4)Tb4b4b4.Te6edf3toHaveBeenCalledWithTb4b4b4(Tb4b4b4{
Te6edf3nameTff7b72: Ta5d6ff"nomadnetwork"Tb4b4b4,
Te6edf3paramsTff7b72: Tb4b4b4{ Te6edf3destinationHashTff7b72: Ta5d6ff"abc123" Tb4b4b4}Tb4b4b4,
Te6edf3queryTff7b72: Tb4b4b4{ Te6edf3pathTff7b72: Ta5d6ff"/p.mu`q=1" Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3nomadEvTb4b4b4.Te6edf3defaultPreventedTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3routerPushTb4b4b4.Te6edf3mockClearTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3fragEv Tff7b72= Te6edf3clickOnTb4b4b4(Te6edf3fragATb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3fragEvTb4b4b4.Te6edf3defaultPreventedTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3fragTargetTb4b4b4.Te6edf3scrollIntoViewTb4b4b4)Tb4b4b4.Te6edf3toHaveBeenCalledTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72finally Tb4b4b4{
Tffa657documentTb4b4b4.Te6edf3bodyTb4b4b4.Te6edf3removeChildTb4b4b4(Te6edf3holderTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72const Te6edf3noop Tff7b72= Tffa657documentTb4b4b4.Te6edf3createElementTb4b4b4(Ta5d6ff"div"Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3noopEv Tff7b72= Tff7b72new Te6edf3MouseEventTb4b4b4(Ta5d6ff"click"Tb4b4b4)Tb4b4b4;
Tffa657ObjectTb4b4b4.Te6edf3definePropertyTb4b4b4(Te6edf3noopEvTb4b4b4, Ta5d6ff"target"Tb4b4b4, Tb4b4b4{ Te6edf3valueTff7b72: Te6edf3noop Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Tb4b4b4(Tb4b4b4) Tb4b4b4=> Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3onArchiveContentClickTb4b4b4(Te6edf3noopEvTb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toThrowTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"onArchiveContentClick opens http links externally"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3openSpy Tff7b72= Te6edf3viTb4b4b4.Te6edf3spyOnTb4b4b4(Tffa657windowTb4b4b4, Ta5d6ff"open"Tb4b4b4)Tb4b4b4.Te6edf3mockImplementationTb4b4b4(Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tff7b72nullTb4b4b4)Tb4b4b4;
Tff7b72const Tb4b4b4{ Te6edf3wrapper Tb4b4b4} Tff7b72= Te6edf3mountArchivesTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3holder Tff7b72= Tffa657documentTb4b4b4.Te6edf3createElementTb4b4b4(Ta5d6ff"div"Tb4b4b4)Tb4b4b4;
Te6edf3holderTb4b4b4.Te6edf3innerHTML Tff7b72= Ta5d6ff'<a href="https://example.com/page">Example</a>'Tb4b4b4;
Tffa657documentTb4b4b4.Te6edf3bodyTb4b4b4.Te6edf3appendChildTb4b4b4(Te6edf3holderTb4b4b4)Tb4b4b4;
Tff7b72try Tb4b4b4{
Tff7b72const Te6edf3link Tff7b72= Te6edf3holderTb4b4b4.Te6edf3querySelectorTb4b4b4(Ta5d6ff"a"Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3ev Tff7b72= Tff7b72new Te6edf3MouseEventTb4b4b4(Ta5d6ff"click"Tb4b4b4, Tb4b4b4{ Te6edf3bubblesTff7b72: Tff7b72trueTb4b4b4, Te6edf3cancelableTff7b72: Tff7b72true Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tffa657ObjectTb4b4b4.Te6edf3definePropertyTb4b4b4(Te6edf3evTb4b4b4, Ta5d6ff"target"Tb4b4b4, Tb4b4b4{ Te6edf3valueTff7b72: Te6edf3link Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3onArchiveContentClickTb4b4b4(Te6edf3evTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3openSpyTb4b4b4)Tb4b4b4.Te6edf3toHaveBeenCalledWithTb4b4b4(Ta5d6ff"https://example.com/page"Tb4b4b4, Ta5d6ff"_blank"Tb4b4b4, Ta5d6ff"noopener,noreferrer"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3evTb4b4b4.Te6edf3defaultPreventedTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72finally Tb4b4b4{
Tffa657documentTb4b4b4.Te6edf3bodyTb4b4b4.Te6edf3removeChildTb4b4b4(Te6edf3holderTb4b4b4)Tb4b4b4;
Te6edf3openSpyTb4b4b4.Te6edf3mockRestoreTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"onArchiveContentClick blocks javascript: anchors without opening a window"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3openSpy Tff7b72= Te6edf3viTb4b4b4.Te6edf3spyOnTb4b4b4(Tffa657windowTb4b4b4, Ta5d6ff"open"Tb4b4b4)Tb4b4b4.Te6edf3mockImplementationTb4b4b4(Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tff7b72nullTb4b4b4)Tb4b4b4;
Tff7b72const Tb4b4b4{ Te6edf3wrapperTb4b4b4, Te6edf3routerPush Tb4b4b4} Tff7b72= Te6edf3mountArchivesTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3holder Tff7b72= Tffa657documentTb4b4b4.Te6edf3createElementTb4b4b4(Ta5d6ff"div"Tb4b4b4)Tb4b4b4;
Te6edf3holderTb4b4b4.Te6edf3innerHTML Tff7b72= Ta5d6ff'<a href="javascript:alert(1)">bad</a>'Tb4b4b4;
Tffa657documentTb4b4b4.Te6edf3bodyTb4b4b4.Te6edf3appendChildTb4b4b4(Te6edf3holderTb4b4b4)Tb4b4b4;
Tff7b72try Tb4b4b4{
Tff7b72const Te6edf3link Tff7b72= Te6edf3holderTb4b4b4.Te6edf3querySelectorTb4b4b4(Ta5d6ff"a"Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3ev Tff7b72= Tff7b72new Te6edf3MouseEventTb4b4b4(Ta5d6ff"click"Tb4b4b4, Tb4b4b4{ Te6edf3bubblesTff7b72: Tff7b72trueTb4b4b4, Te6edf3cancelableTff7b72: Tff7b72true Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tffa657ObjectTb4b4b4.Te6edf3definePropertyTb4b4b4(Te6edf3evTb4b4b4, Ta5d6ff"target"Tb4b4b4, Tb4b4b4{ Te6edf3valueTff7b72: Te6edf3link Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3onArchiveContentClickTb4b4b4(Te6edf3evTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3evTb4b4b4.Te6edf3defaultPreventedTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3openSpyTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toHaveBeenCalledTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3routerPushTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toHaveBeenCalledTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72finally Tb4b4b4{
Tffa657documentTb4b4b4.Te6edf3bodyTb4b4b4.Te6edf3removeChildTb4b4b4(Te6edf3holderTb4b4b4)Tb4b4b4;
Te6edf3openSpyTb4b4b4.Te6edf3mockRestoreTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────